/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2012-2019. All rights reserved.
 * Description:
 * Author: huawei
 * Create: 2019/6/18
 */
#ifndef _DEV_COMMON_H_
#define _DEV_COMMON_H_

#include <linux/types.h>
#include <asm/io.h>

#define DEVDRV_SYSCTL_BASE_ADDR 0x1100c0000
#define DEVDRV_SYSCTL_SIZE 0x10000
#define DEVDRV_SYSCTL_PLTFORM_REG 0xfffc

#define DEVDRV_PLATFORM_TYPE_FPGA 0
#define DEVDRV_PLATFORM_TYPE_EMU 1
#define DEVDRV_PLATFORM_TYPE_ESL 2
#define DEVDRV_PLATFORM_TYPE_ASIC 3

/*
 * p_type stores the platform type: 0-FPGA 1-EMU 2-ESL 3-ASIC
 * version stores the soc version: 0x300 matchs b300,
 * 0x201 matchs b201 , as so on.
 */
static inline int devdrv_get_platform_type(unsigned int *p_type, unsigned int *version)
{
    void __iomem *sysctl_base = NULL;
    unsigned int reg_val;
    unsigned int type_val;
    int ret;

    ret = 0;
    sysctl_base = ioremap(DEVDRV_SYSCTL_BASE_ADDR, DEVDRV_SYSCTL_SIZE);
    if (sysctl_base == NULL) {
        pr_err("sysctl_addr ioremap failed\n");
        return -1;
    }

    reg_val = readl_relaxed((void *)((u64)(uintptr_t)sysctl_base + DEVDRV_SYSCTL_PLTFORM_REG));
    type_val = reg_val >> 16;

    *version = reg_val & 0xffff;
    *p_type = 0xff;

    if (((type_val & 0x3) == 0) && (*version == 0)) {
        *p_type = DEVDRV_PLATFORM_TYPE_ASIC;
    } else if ((type_val & 0x3) == 0) {
        *p_type = DEVDRV_PLATFORM_TYPE_FPGA;
    } else if ((type_val & 0x3) == 2) {
        *p_type = DEVDRV_PLATFORM_TYPE_ESL;
    } else if ((type_val & 0x3) == 1) {
        *p_type = DEVDRV_PLATFORM_TYPE_EMU;
    } else {
        pr_err("platform type err, check soc config!\n");
        ret = -1;
    }

    *version = reg_val & 0xffff;
    iounmap(sysctl_base);
    sysctl_base = NULL;
    return ret;
}

#endif
